//This file is part of Image Mining Framework.
//
//    Image Mining Framework is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    Image Mining Framework is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with Image Mining Framework.  If not, see <http://www.gnu.org/licenses/>.

import ij.*;
import ij.WindowManager;
import java.awt.event.ActionListener;
import java.lang.Math.*;
import ij.process.ImageProcessor;
import java.awt.image.*;
import java.io.*;
import java.awt.Color.*;
import ij.gui.GenericDialog;
import ij.io.DirectoryChooser;
import ij.plugin.filter.PlugInFilter;
import java.awt.Rectangle;
import ij.text.TextWindow;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Class featureVector_ is an ImageJ plugin that implements the
 * selective sliding window algorithm proposed by D.K. Iakovidis in IST 2008 and BIBE 2008.
 * @author Michael Dompekidis and Dimitris K. Iakovids
 **/
public class ClusterFeatures_ implements PlugInFilter, WindowListener, ActionListener
{
  private int       boxWidth,
                    boxHeight,
                    boxStepX,boxStepY,n;
  private boolean localSave;
  TextWindow textLog;
 
  String finalString = "Feature Vector"+"\n"+"\n";
  public BufferedImage betaImg;
  public BufferedImage IMFImage;
  public Boolean oneRun = true;
  public BufferedWriter bufferedWriter = null;
  public  BufferedWriter out;
  public int counter = 0;
  public Button button1;
  public String dir = "";

  public int setup(String arg, ImagePlus imp)
  {
        imp = WindowManager.getCurrentImage();
        return DOES_ALL;
  }
@SuppressWarnings({"deprecation","unchecked"})

  public void run(ImageProcessor ip)
  {
        // Default values
        boxWidth    = 24;
        boxHeight   = 24;
        boxStepX    = 1;
        boxStepY    = 1;
        localSave   = true;
        n           = 2;
        ImagePlus imp = WindowManager.getCurrentImage();
        //getting the area of interest that the user might have choosen
        Rectangle areaOfInterest = imp.getProcessor().getRoi();
        //if(areaOfInterest.width!=boxWidth&&areaOfInterest.width!=0)boxWidth=areaOfInterest.width;
        //if(areaOfInterest.height!=boxHeight&&areaOfInterest.height!=0)boxHeight=areaOfInterest.height;

        // Creates a new window on ImageJ where text, or GUI elements are added.
        button1 = new Button("...");
        button1.addActionListener(this);
        GenericDialog gd = new GenericDialog("Feature Vector sampler");
        gd.addMessage("Sampling box preferences: ");
        gd.addNumericField("Width of the Box", boxWidth,1);
        gd.addNumericField("Height of the Box", boxHeight,1);
        gd.addNumericField("Box pacing on X-axis", boxStepX,1);
        gd.addNumericField("Box pacing on Y-axis", boxStepY,1);
        gd.addNumericField("Clusters",n, 1);
     
        gd.addCheckbox("Save featureVectors ", localSave);
        gd.setInsets(20, 15, 10);
        Panel pd = new Panel();
        pd.setLayout(new FlowLayout(FlowLayout.CENTER,0,0));
        pd.add(button1);
        gd.addPanel(pd,GridBagConstraints.EAST, new Insets(-20,5,5,0));

        gd.showDialog();
        if(gd.wasCanceled())
        {
            IJ.error("Plugin canceled");
            return;
        }

        // Get GUI values
        boxWidth = (int)gd.getNextNumber();
        boxHeight = (int)gd.getNextNumber();
        boxStepX = (int)gd.getNextNumber();
        boxStepY = (int)gd.getNextNumber();
        n        = (int)gd.getNextNumber();
        if(gd.invalidNumber())
        {
            IJ.error("Invalid field");
            return;
        }
        //Checkbox value
        localSave = gd.getNextBoolean();
      
        imp.updateAndDraw();
       // IJ.log("Channel: "+String.valueOf(ip.getNChannels()));
        WindowScanner featureUtil = new WindowScanner();

        //Start sliding window with inputs from dialog window.
        int[][][][] featureVector = featureUtil.slidingWindow(ip, boxWidth, boxHeight, boxStepX, boxStepY, areaOfInterest,String.valueOf(ip.getNChannels()));
        
        imp.flush();

        featureUtil.saveFeatures(featureVector,  boxWidth, boxHeight, featureVector[0].length, featureVector.length, n, dir, localSave,true);

        featureVector = new int[1][][][];

        imp.flush();

        //required by imageJ
        return;
    }


    public void actionPerformed(ActionEvent e)
	{
            Object b = e.getSource();
            if (b==button1)
            {
                DirectoryChooser dc = new DirectoryChooser("Save at...");
                dir = dc.getDirectory();
                if (dir==null) Macro.abort();
            } 
	else
	{}

        }

   
    public void windowClosing(WindowEvent e)
    {
        try {
            textLog.close();

            //WindowManager.closeAllWindows();
            WindowManager.removeWindow(textLog);
            oneRun = false;
            textLog.dispose();
            this.finalize();
        } catch (Throwable ex) {
            Logger.getLogger(ClusterFeatures_.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
   

 
    public void windowOpened(WindowEvent e)
    {

    }

    public void windowClosed(WindowEvent e)
    {

    }

    public void windowIconified(WindowEvent e)
    {

    }

    public void windowDeiconified(WindowEvent e)
    {

    }

    public void windowActivated(WindowEvent e)
    {

    }

    public void windowDeactivated(WindowEvent e)
    {

    }

    
}


